﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HotelBookingSystem
{
    public class Manager
    {
        private int MaxDay;
        private const int MaxBookings = 100;
        protected ArrayList bookings;
        protected ArrayList units;

        private int[, ,] numCust;

        public Manager(int MaxDay, int MaxUnit)
        {
            //TypeReservalbe type = new TypeReservalbe();
            ////string[] str = Enum.GetNames(type);
            //Enum.GetNames(typeof(TypeReservalbe)).Length;
            this.MaxDay = MaxDay;
            numCust = new int[MaxDay, MaxUnit, 3];
            units = new ArrayList();
            bookings = new ArrayList();
        }
        public int NumberUnits
        {
            get
            {
                return units.Count;
            }
        }
        public int NumberReservations
        {
            get
            {
                return bookings.Count;
            }
        }

        public BookingResult Book(Booking res)
        {
            int unitid = res.UnitId;
            DateTime dt = res.Date;
            int numDays = res.NumberDays;
            TypeBookable type = res.bookableType;
            BookingResult result = new BookingResult();
            Bookable unit = FindUnit(unitid);
            // Check that unit exitst// check for unitid?
            if (unit == null)
            {
                throw new NotFoundException();
            }
            // Check if dates are within supported range
            int day = dt.DayOfYear - 1;
            if (day + numDays > MaxDay)
            {
                  throw new DateOutOfRangeException();
            }
            // Check if rooms are available for all dates
            for (int i = day; i < day + numDays; i++)
            {
                //try/catch?
                try
                {
                    if (numCust[i, unitid, (int)type] >= unit.typeCap[(int)type])
                {
                        throw new NotAvailableException();
                    }
                }
                catch (NotAvailableException)
                {
                    Console.WriteLine("Not available");
            }


            }
            // Reserve a room for requested dates
            for (int i = day; i < day + numDays; i++)
                numCust[i, unitid, (int)type] += 1;
            // Add reservation to reservation list and return result
            AddBooking(res);
            result.BookingId = res.BookingId;
            result.BookingCost = unit.cost * numDays;
            result.Rate = unit.cost;
            result.Comment = "OK";
            return result;
        }

        public void CancelBooking(int id)
        {
            Booking res = FindBooking(id);
            if (res == null)
                throw new NotFoundException();// add exception class
            // Release the room
            int day = res.Date.DayOfYear;
            int numDays = res.NumberDays;
            int unitid = res.UnitId;
            for (int i = day; i < day + numDays; i++)
                numCust[i, unitid, (int)res.bookableType] -= 1;

            bookings.Remove(res);
        }
        private Booking FindBooking(int id)
        {
            foreach (Booking res in bookings)
            {
                if (res.BookingId == id)
                    return res;// add exception?
            }
            return null;
        }
        private void AddBooking(Booking res)
        {
            bookings.Add(res);
        }
        protected void AddUnit(Bookable unit)
        {
            units.Add(unit);
        }
        private Bookable FindUnit(int id)
        {
            foreach (Bookable unit in units)
            {
                if (unit.unitid == id)
                    return unit;// add exception?
            }
            return null;
        }
    }
}